import datetime
import random
import re
from enums.sys_type_enum import SysTypeEnum
# from curl_cffi import requests
import requests
import js2py
import time
from utils.common.scheduler import scheduler
import execjs
from utils.ip_proxy.pinzan_ip_proxy import PinzanHttpProxy
from urllib.parse import urlparse
import env_config
import json
from utils.submit_ua import UserAgentGenerate
from bs4 import BeautifulSoup
import random
import string
from enum import Enum
from utils.common.init_app import app
from utils.commit.oversea_regions import OVERSEA_REGIONS
from urllib.parse import quote

session = requests.Session()


class WjxSubmitTypeEnum(Enum):
    WX = "WX"  # 微信
    PHONE = "PHONE"  # 手机
    PC = "PC"  # 直接提交


class IpProxy(object):
    def __init__(self, region):
        self.sessions = session
        self.region = region

    def get_ip_proxy(self):
        time.sleep(random.uniform(1, 5))
        r = self.sessions.get("https://share.proxy.qg.net/get?key=S0H7ZGI6&num=1&distinct=true&pool=1",
                              impersonate="chrome101")
        proxies = {}
        area = ''
        status_code = r.status_code
        if status_code == 200:
            json_data = r.json()
            if json_data.get('code') == 'SUCCESS':
                datas = json_data.get('data')
                if datas:
                    obj = datas[0]
                    area = obj.get('area')  # 区域 - "江苏省南通市",
                    # isp = obj.get('isp')  # 区域 - "isp": "电信",
                    # deadline = obj.get('deadline')  # ip可用时间截至日期 - "deadline": "2023-10-08 23:48:14"
                    # proxy_ip = obj.get('proxy_ip')  # ip地址 -  "proxy_ip": "180.121.135.48",
                    server = obj.get('server')  # ip+端口号 - "server": "180.121.135.48:35341",
                    proxy_url = "http://%(user)s:%(password)s@%(server)s" % {
                        "user": 'S0H7ZGI6',
                        "password": '916FBAA4A876',
                        "server": server,
                    }
                    proxies = {"http": proxy_url, "https": proxy_url}
        return proxies, area


class QuestionareSpider(object):
    def __init__(self, send_title_link, pz_obj, wo_topic_id, sleep_time, area):
        self.sessions = session
        # self.proxy_obj = proxy_obj
        self.pz_obj: PinzanHttpProxy = pz_obj
        self.title_link = send_title_link
        self.wo_topic_id = wo_topic_id
        self.headers = {}
        self.sleep_time = sleep_time or 20  # 问卷需要填写的时间,默认20秒
        self.area = area
        self.ua = UserAgentGenerate.random_phone_micro_messenger()  # 初始化实例默认获取一个ua
        self.can_get_7_code = True

    def is_ip_available(self):
        if self.pz_obj.expired < int(time.time() * 1000):
            # ip已过期，重新获取ip
            # print('ip已过期，重新获取ip===================================')
            self.pz_obj.get_proxy()

    def get_jqsign(self, ktimes: int, jqnonce: str):
        result = []
        b = ktimes % 10 if ktimes % 10 != 0 else 1
        for char in list(jqnonce):
            f = ord(char) ^ b
            result.append(chr(f))
        return ''.join(result)

    def get_jqpraram(self, rndnum, activityId, starttime):
        with open('./js_file/questionare_.js', 'r', encoding='utf8') as f:
            script = f.read()
        # context = js2py.EvalJs(enable_require=True)
        context = js2py.EvalJs()
        context.execute(script)
        ts = int(time.mktime(time.strptime(starttime, "%Y/%m/%d %H:%M:%S")))
        return context._0x156205(rndnum, ts, activityId)

    def get_jqpraram_v2(self, rndnum, activityId, starttime):
        with open('./js_file/questionare_.js', 'r', encoding='utf8') as f:
            script = f.read()
        context = execjs.compile(script)
        ts = int(time.mktime(time.strptime(starttime, "%Y/%m/%d %H:%M:%S")))
        result = context.call('_0x156205', rndnum, ts, activityId)
        return result

    def get_cookies(self):
        # 设置微信提交的header
        self.headers['upgrade-insecure-requests'] = '1'
        self.headers['user-agent'] = self.ua
        self.headers['accept'] = ('text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,'
                                  'image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9')
        self.headers['sec-fetch-site'] = 'none'
        self.headers['sec-fetch-mode'] = 'navigate'
        self.headers['sec-fetch-user'] = '?1'
        self.headers['sec-fetch-dest'] = 'document'
        self.headers['accept-encoding'] = 'gzip, deflate, br'
        self.headers['accept-language'] = 'zh-CN,zh'
        response = requests.get(url=self.title_link, headers=self.headers, timeout=10, proxies=self.pz_obj.proxies,
                                allow_redirects=False)
        return response.content

    def need_aliyun_smart_check(self, content):
        """
        判断是否需要阿里云的智能验证
        :param content:
        :return:
        """
        # 使用正则表达式匹配数字
        pattern = r'var useAliVerify =(\d+);'
        matches = re.findall(pattern, content)
        res = False
        for match in matches:
            if '1' == str(match):  # 0不需要校验，1需要校验
                res = True
            # print('是否需要阿里云的智能验证:', res)
        return res

    def only_wx_submit(self, content):
        """
        是否只允许在微信中作答
        :return:
        """
        # 使用正则表达式匹配指定元素
        res = False
        try:
            pattern = r'<span class="wxtxt">(.*?)</span>'
            matchs = re.findall(pattern, content)
            for match in matchs:
                if match:
                    # if match == '只允许在微信中作答，请通过微信进行答题':
                    if match == "'+wechatOnly+'":
                        res = True
        except Exception as wx_submit_e:
            print('only_wx_submit judge error')
        finally:
            return res

    def get_params_wjx_m(self, content, submit_type):
        # 样例：https://www.wjx.cn/m/18475388.aspx#
        time.sleep(random.uniform(0, 1))  # 随机sleep0-2秒，改变一下提交时间
        pattern = r'action=".*?curid=(\d+)"'
        curid_match = re.search(pattern, content)
        curid = 0
        if curid_match:
            curid = curid_match.group(1)
            # print(curid)
        # ktimes 为鼠标移动次数
        ktimes = random.randint(57, 143) + int(random.random() * 286)
        jqnonce = re.search(r'var jqnonce="(.+?)";', content).group(1)
        rndnum = re.search(r'var rndnum="(.+?)";', content).group(1)
        activityId = re.search(r'activityId =(\d+);', content).group(1)
        activityId = int(activityId) ^ 2130030173
        current_time = datetime.datetime.now()  # 获取当前时间
        cur_time_unix = int(current_time.timestamp() * 1000)  # 获取当前时间的时间戳
        previous_time = current_time - datetime.timedelta(seconds=self.sleep_time)  # 获取当前时间的sleep_time秒之前的时间
        start_time = previous_time.strftime("%Y/%m/%d %H:%M:%S")
        params = {
            'curid': curid,
            'starttime': start_time,
            'submittype': 1,
            'ktimes': ktimes,
            'hlv': 1,
            'rn': rndnum,
            'jqpram': self.get_jqpraram_v2(rndnum, str(activityId), start_time),
            'nw': '1',
            'jwt': '4',
            'jpm': '83',
            't': cur_time_unix,
            'jqnonce': jqnonce,
            'jqsign': self.get_jqsign(ktimes, jqnonce),
            # 'source': 'directphone',  # 手机提交
            # 'iwx': '1',  # 微信提交 - 默认全部微信提交
        }
        if WjxSubmitTypeEnum.WX == submit_type:
            # 如果需要则使用微信提交
            params['iwx'] = 1
            params['source'] = 'directphone'
        elif WjxSubmitTypeEnum.PHONE == submit_type:
            params['source'] = 'directphone'
        else:  # 默认直接提交
            pass
        # 匹配是否只允许在微信中作答，若只允许在微信中作答，则增加三个参数
        params = self.get_access_token_param(content, params)
        # 判断是否需要智能验证
        if self.need_aliyun_smart_check(content):
            params = self.get_error_code_7_need_token(params, submit_type)
        return activityId, params

    def get_params(self, content, submit_type: WjxSubmitTypeEnum):
        time.sleep(random.uniform(0, 1))  # 随机sleep0-2秒，改变一下提交时间
        cur_link = self.title_link
        parsed_url = urlparse(cur_link)
        path = parsed_url.path.strip('/')
        segments = path.split('/')
        required_string = segments[-1]
        title_short_id = required_string.split('.')[0]
        # ktimes 为鼠标移动次数
        ktimes = random.randint(57, 143) + int(random.random() * 286)
        # jqnonce = re.search(r'.{8}-.{4}-.{4}-.{4}-.{12}', content).group()
        # rndnum = re.search(r'\d{9,10}\.\d{8}', content).group()
        jqnonce = re.search(r'var jqnonce="(.+?)";', content).group(1)
        rndnum = re.search(r'var rndnum="(.+?)";', content).group(1)
        # start_time = re.search(r'\d+?/\d+?/\d+?\s\d+?:\d{2}:\d{2}', content).group()
        activityId = re.search(r'activityId =(\d+);', content).group(1)
        activityId = int(activityId) ^ 2130030173
        current_time = datetime.datetime.now()  # 获取当前时间
        cur_time_unix = int(current_time.timestamp() * 1000)  # 获取当前时间的时间戳
        previous_time = current_time - datetime.timedelta(seconds=self.sleep_time)  # 获取当前时间的sleep_time秒之前的时间
        start_time = previous_time.strftime("%Y/%m/%d %H:%M:%S")
        params = {
            'shortid': title_short_id,
            'starttime': start_time,
            'submittype': 1,
            'ktimes': ktimes,
            'hlv': 1,
            'rn': rndnum,
            'jqpram': self.get_jqpraram_v2(rndnum, str(activityId), start_time),
            'nw': '1',
            'jwt': '4',
            'jpm': '83',
            't': cur_time_unix,
            'jqnonce': jqnonce,
            'jqsign': self.get_jqsign(ktimes, jqnonce),
            # 'source': 'directphone',  # 手机提交
            # 'iwx': '1',  # 微信提交 - 默认全部微信提交
        }
        if WjxSubmitTypeEnum.WX == submit_type:
            # 如果需要则使用微信提交
            params['iwx'] = 1
            params['source'] = 'directphone'
        elif WjxSubmitTypeEnum.PHONE == submit_type:
            params['source'] = 'directphone'
        else:  # 默认直接提交
            pass
        # 匹配是否只允许在微信中作答，若只允许在微信中作答，则增加三个参数
        params = self.get_access_token_param(content, params)
        # 判断是否需要智能验证
        if self.need_aliyun_smart_check(content):
            params = self.get_error_code_7_need_token(params, submit_type)
        # 获取A公众号的access_token，发送这个token到wjx的后台，测试能否显示用户的信息
        # print(params)
        return activityId, params

    def get_access_token_param(self, content, params):
        def random_lowercase(length: int):
            characters = string.ascii_lowercase
            random_string = ''.join(random.choices(characters, k=length))
            return random_string

        def random_uppercase_lowercase_digit(length: int):
            characters = string.ascii_letters + string.digits
            random_string = ''.join(random.choices(characters, k=length))
            return random_string

        if self.only_wx_submit(content):
            # print('只允许在微信中作答， 增加微信提交的参数')
            # unionid 和 openid用来校验是不是重复的用户，access_token用来获取用户的昵称等信息
            # 若不传unionid和openid每次都一样，会报错：5〒很抱歉，每个用户只能填写1次，您已达到最大参与次数！
            # 若不传access_token，会报错：5〒很抱歉，必须微信登录才能填写！
            # 'unionid': 'fjwioejfijscmsdl3',  # 可以随机字符串，无所谓
            # 'openid': 'sdjfksldjfsdklfjdslfs2',  # 可以随机字符串，无所谓
            # 'access_token': '74_E7AiIuJNrVS-mHFNVPmdlP2PY5aozd7Dx3MN_9WLbjIELIvm2-_9cvXFToz7kVrgbLGKH76OsAFdxi4YLfR7kys_JoovvraUsq0yO3rppxw',
            params['unionid'] = random_lowercase(16)
            params['openid'] = random_lowercase(21)
            # 随便模拟access_token
            ac_str = '74_' + random_uppercase_lowercase_digit(11) + '-' + random_uppercase_lowercase_digit(
                24) + '_' + random_uppercase_lowercase_digit(
                random.randint(12, 17)) + '-_' + random_uppercase_lowercase_digit(
                random.randint(36, 38)) + '_' + random_uppercase_lowercase_digit(random.randint(19, 21))
            params['access_token'] = ac_str
        return params

    def get_error_code_7_need_token(self, submit_type: WjxSubmitTypeEnum) -> json:
        inner_pz_obj = self.pz_obj  # 通过获取到的代理对象获取url
        proxy_meta = inner_pz_obj.proxy_meta
        # print('结果以7开头')
        # 如果以7开头，则说需要智能验证，获取智能验证码
        # 1. 调用js代码，获取智能验证码
        config = env_config.config_mapping()
        sig_token_url = config.get('WJX_7_CHECK_SERVER')
        wo_topic_id = self.wo_topic_id
        app.logger.info('发送阿里云smart_code的wo_topic_id是:' + wo_topic_id + ',sig_token_url:' + sig_token_url)
        url = '%s/sign' % sig_token_url
        params = dict()
        params['url'] = self.title_link
        params['proxy_url'] = proxy_meta
        params['work_order_id'] = wo_topic_id
        params['submit_type'] = submit_type.value
        app.logger.info('发送阿里云url:' + url)
        # callback_response = requests.post(url, params=params)
        callback_response = requests.post(url=url, data=params, timeout=10, allow_redirects=False)
        data = callback_response.content.decode()
        # print('获取到的data:', data)
        return data

    def get_submit_result(self, submitdata, submit_type):
        """
        提交问卷
        :param submitdata: 需要提交数据
        :return:
        """
        # 1. 获取提交参数
        # send_param = self.get_base_param(submit_type)
        send_param = self.get_base_param_v2(submit_type)
        url = "https://www.wjx.cn/joinnew/processjq.ashx"
        cur_header = dict()
        cur_header['Origin'] = 'https://www.wjx.cn'
        cur_header["Host"] = 'www.wjx.cn'
        cur_header['content-type'] = 'application/x-www-form-urlencoded; charset=UTF-8'
        cur_header['user-agent'] = self.ua  # 模拟微信请求头
        cur_header["Referer"] = self.title_link
        # 2. 判断ip是否可用
        self.is_ip_available()  # 判断当前ip是否过期，如果过期重新获取一个ip并且立即发送请求
        # 3. 发送请求
        # print('send_param:', send_param)
        # print('area：', self.area)
        if self.area in OVERSEA_REGIONS:  # 海外发送请求
            # print('发送到海外服务器')
            # 1, 获取海外的代理地址，2，发送到海外服务器
            upper_area = self.area.upper()
            p_url = 'http://cuveecui-' + upper_area + ':yydj8888@proxy.smartproxycn.com:1000'
            oversea_param_dict = dict()
            oversea_param_dict['submit_data'] = {'submitdata': submitdata}
            oversea_param_dict['request_headers'] = cur_header
            oversea_param_dict['proxy_url'] = p_url
            oversea_send_url = url + '?'
            if send_param:
                num_items = len(send_param)
                current_item = 0
                for key, value in send_param.items():
                    current_item += 1
                    # oversea_send_url += quote(str(key)) + '=' + quote(str(value))
                    oversea_send_url += str(key) + '=' + str(value)
                    if current_item == num_items:  # 判断是否是最后一个键值对，最后一个结尾不需要&符号
                        pass
                    else:
                        oversea_send_url += '&'
            encoded_url = oversea_send_url
            oversea_param_dict['url'] = encoded_url
            # print('打印请求参数：')
            # print(oversea_param_dict)
            sys_oversea_url = 'http://8.137.54.97:7002/api/overseas/submit'
            oversea_header = dict()
            # oversea_header['content-type'] = 'application/json; charset=UTF-8'
            res = requests.post(url=sys_oversea_url, headers=oversea_header, json=oversea_param_dict, timeout=10)
            oversea_response = res.json()
            if (oversea_response and 200 == oversea_response.get('code')
                    and 'success' == oversea_response.get('message')):
                pd = res.content.decode()  # oversea_response.get('result')
            else:
                pd = '发送海外数据失败'
        else:  # 默认国内直接发送
            res = requests.post(url=url, headers=cur_header, params=send_param, data={'submitdata': submitdata},
                                timeout=10,
                                proxies=self.pz_obj.proxies, allow_redirects=False)
            pd = res.content.decode()
        # print('pd', pd)
        return pd

    def submit(self, submitdata):
        """
        提交问卷
        :param submitdata: 需要提交数据
        :return:
        """
        pd = self.get_submit_result(submitdata, WjxSubmitTypeEnum.WX)  # 默认微信提交
        if pd.startswith('10〒'):
            pass
        elif pd.startswith('5〒'):  # 5〒很抱歉，必须微信登录才能填写！
            # 默认就是微信提交，说明此时不应该再用微信提交，则转为使用手机提交
            self.ua = UserAgentGenerate.random_pc()  # 获取pd的ua
            pd = self.get_submit_result(submitdata, WjxSubmitTypeEnum.PHONE)
        elif pd.startswith('7〒'):  # 需要智能验证
            pass
        else:
            pass
        return pd

    def get_base_param(self, submit_type: WjxSubmitTypeEnum):
        content = self.get_cookies()
        decode_content = content.decode()
        # 2. 组装普通参数
        if self.title_link.startswith('https://www.wjx.cn/m/'):  # 如果是通过 https://www.wjx.cn/m 开头的，则通过另一种形式获取参数
            # print('通过 https://www.wjx.cn/m/ 开头')
            params = self.get_params_wjx_m(decode_content, submit_type)
        else:  # 默认通过这种方式发送
            # print('普通开头')
            params = self.get_params(decode_content, submit_type)
        return params[1]

    def get_base_param_v2(self, submit_type: WjxSubmitTypeEnum):
        # 样例：https://www.wjx.cn/m/18475388.aspx#
        # 0. 发送请求，获取链接
        base_content = self.get_cookies()
        content = base_content.decode()
        time.sleep(random.uniform(0, 1))  # 随机sleep0-2秒，改变一下提交时间
        # 1. 封装默认参数
        ktimes = random.randint(57, 143) + int(random.random() * 286)  # ktimes 为鼠标移动次数
        jqnonce = re.search(r'var jqnonce="(.+?)";', content).group(1)
        rndnum = re.search(r'var rndnum="(.+?)";', content).group(1)
        activityId = re.search(r'activityId =(\d+);', content).group(1)
        activityId = int(activityId) ^ 2130030173
        current_time = datetime.datetime.now()  # 获取当前时间
        cur_time_unix = int(current_time.timestamp() * 1000)  # 获取当前时间的时间戳
        previous_time = current_time - datetime.timedelta(seconds=self.sleep_time)  # 获取当前时间的sleep_time秒之前的时间
        start_time = previous_time.strftime("%Y/%m/%d %H:%M:%S")
        params = {
            'starttime': start_time,
            'submittype': 1,
            'ktimes': ktimes,
            'hlv': 1,
            'rn': rndnum,
            'jqpram': self.get_jqpraram_v2(rndnum, str(activityId), start_time),
            'nw': '1',
            'jwt': '4',
            'jpm': '83',
            't': cur_time_unix,
            'jqnonce': jqnonce,
            'jqsign': self.get_jqsign(ktimes, jqnonce),
        }
        # 2. 封装id参数
        if self.title_link.startswith('https://www.wjx.cn/m/'):  # 如果是通过 https://www.wjx.cn/m 开头的，则通过另一种形式获取参数
            pattern = r'action=".*?curid=(\d+)"'
            curid_match = re.search(pattern, content)
            curid = 0
            if curid_match:
                curid = curid_match.group(1)
            params['curid'] = curid
        else:  # 默认通过这种方式发送
            cur_link = self.title_link
            parsed_url = urlparse(cur_link)
            path = parsed_url.path.strip('/')
            segments = path.split('/')
            required_string = segments[-1]
            title_short_id = required_string.split('.')[0]
            params['shortid'] = title_short_id
        # 3. 判断是否需要智能验证
        if self.need_aliyun_smart_check(content):
            smart_result_str = self.get_error_code_7_need_token(submit_type)
            smart_result = json.loads(smart_result_str)
            # print(smart_result)
            # print('type:', type(smart_result))
            smart_check_code = smart_result.get('code')
            smart_check_status = smart_result.get('status')
            if 200 == smart_check_code:
                # print('smart_check_success')
                if 4000 == smart_check_status:
                    # print('smart_check_4000')
                    pass
                elif 4001 == smart_check_status:  # pc
                    # print('smart_check_4001')
                    smart_result_str = self.get_error_code_7_need_token(WjxSubmitTypeEnum.PC)
                    smart_result = json.loads(smart_result_str)
                    smart_check_code = smart_result.get('code')
                    smart_check_status = smart_result.get('status')
                elif 4002 == smart_check_status:  # getNVCval获取失败
                    # print('smart_check_4002')
                    self.can_get_7_code = False
                elif 4003 == smart_check_code:  # 服务代码有问题
                    # print('smart_check_4003')
                    self.can_get_7_code = False
            else:
                self.can_get_7_code = False
            # print(smart_result)
            if smart_result and 200 == smart_check_code and 4000 == smart_check_status and self.can_get_7_code:
                # print('smart_result请求成功')
                smart_inner_result = smart_result.get('result')
                if smart_inner_result:
                    # print('token数据：', smart_inner_result)
                    # data_json = json.loads(smart_inner_result)
                    data_json = smart_inner_result
                    sign = data_json.get('sign')
                    inner_data = data_json.get('data')
                    if sign and inner_data:  # 若都获取到，则继续往下解析，否则直接返回
                        # 提取有效的JSON部分，并解析为JSON对象
                        # sign_data = inner_data[inner_data.index('(') + 1: inner_data.rindex(')')]
                        # sign_res = json.loads(sign_data)
                        sign_res = inner_data
                        nc_csessionid = ''
                        nc_sig = ''
                        nc_token = ''
                        nc_scene = ''
                        if sign_res:
                            sig_success = sign_res.get('success')
                            if sig_success:
                                sig_result = sign_res.get('result')
                                if sig_result and sig_result.get('success') and sig_result.get('code') == 200:
                                    # 说明获取成功
                                    inner_result = sig_result.get('result')
                                    if inner_result:
                                        nc_csessionid = inner_result.get('sessionId')
                                        nc_sig = inner_result.get('sig')
                        # sign_cookie = json.loads(sign)
                        sign_cookie = sign
                        if sign_cookie:
                            # a = sign_cookie.get('a')
                            nc_token = sign_cookie.get('c')
                            nc_scene = sign_cookie.get('d')
                        # 2. 立即继续发送:拿到4个参数，组装对象继续提交
                        params['nc_csessionid'] = nc_csessionid
                        params['nc_sig'] = nc_sig
                        params['nc_token'] = nc_token
                        params['nc_scene'] = nc_scene
                        # print('nc_csessionid:', nc_csessionid, ',nc_sig:', nc_sig, ',nc_token:', nc_token, ',nc_scene:',
                        #       nc_scene)
                # print(params)
        # 4. 判断提交类型
        if WjxSubmitTypeEnum.WX == submit_type:  # 如果需要则使用微信提交
            params['iwx'] = 1
            params['source'] = 'directphone'
        elif WjxSubmitTypeEnum.PHONE == submit_type:
            params['source'] = 'directphone'
        else:  # 默认直接提交
            pass
        # 5. 判断是否只允许在微信中作答，若只允许在微信中作答，则增加三个参数
        params = self.get_access_token_param(content, params)
        # print('5_param', params)
        # return activityId, params
        return params


def convert_data_to_submit_data(db_title_arr, db_res_arr) -> str:
    """
    将数据库中的数据转换为需要提交的结果数据
    :param db_title_arr: 题目与数据库结果的映射关系数组
    :param db_res_arr: 需要提交的答案数组
    :return:
    """
    res = ''
    for index in range(len(db_title_arr)):
        i = db_title_arr[index]
        indexes = i['data_index']
        cur_type = i['sys_type']
        s = i['title_id'] + '$'
        if len(indexes) > 1:
            if cur_type == SysTypeEnum.MULTIPLE.value:  # 多选题
                cur_s = ''
                for j in range(len(indexes)):
                    mu_arr = str(db_res_arr[indexes[j]]).split('^')
                    if mu_arr and mu_arr[0] == '1':  # 如果为1，表示需要提交这个选项
                        if cur_s != '':
                            cur_s += '|'
                        cur_s += str(j + 1)
                        if len(mu_arr) >= 2:
                            cur_s += '^' + str(mu_arr[1])
                if cur_s == '':  # 如果没有任何一个选项选择了，则表示这个题直接跳过
                    cur_s = '-3'
                s += cur_s
            elif cur_type == SysTypeEnum.MATRIX.value:
                for j in range(len(indexes)):
                    s += str(j + 1) + '!' + str(db_res_arr[indexes[j]])
                    if j < len(indexes) - 1:
                        s += ','
            elif cur_type == SysTypeEnum.SLIDE.value or cur_type == SysTypeEnum.RATE.value:
                cur_s = ''
                for j in range(len(indexes)):
                    if cur_s != '':
                        cur_s += '^'
                    cur_s += str(j + 1) + '!' + str(db_res_arr[indexes[j]])
                    # if j > len(indexes) - 1:
                    #     s += '^'
                s += cur_s
            elif cur_type == SysTypeEnum.SORTED.value:  # 排序题
                for j in range(len(indexes)):
                    s += str(db_res_arr[indexes[j]])
                    if j < len(indexes) - 1:
                        s += ','
            elif cur_type == SysTypeEnum.MULTIPLE_TEXT.value:  # 多项填空
                for j in range(len(indexes)):
                    s += str(db_res_arr[indexes[j]])
                    if j < len(indexes) - 1:
                        s += '^'
            elif cur_type == SysTypeEnum.MULTIPLE_MATRIX.value:  # 矩阵多选
                children = i['children']
                multiple_s = ''
                for child_index in range(len(children)):
                    child = children[child_index]
                    child_options = child['options']
                    if multiple_s != '':
                        multiple_s += ','
                    multiple_s += str(child_index + 1) + '!'
                    cur_s = ''
                    for j in range(len(child_options)):
                        mu_arr = str(db_res_arr[child_options[j]['data_index']]).split('^')
                        if mu_arr and mu_arr[0] == '1':  # 如果为1，表示需要提交这个选项
                            if cur_s != '':
                                cur_s += ';'
                            cur_s += str(j + 1)
                            if len(mu_arr) >= 2:
                                cur_s += '^' + str(mu_arr[1])
                    multiple_s += cur_s
                s += multiple_s
            elif cur_type == SysTypeEnum.MATRIX_TEXT.value:  # 矩阵填空
                cur_s = ''
                for j in range(len(indexes)):
                    if cur_s != '':
                        cur_s += '^'
                    cur_s += str(j + 1) + '!' + str(db_res_arr[indexes[j]])
                s += cur_s
            else:
                for j in range(len(indexes)):
                    s += str(db_res_arr[indexes[j]])
        else:
            s += str(db_res_arr[indexes[0]])
        if index < len(db_title_arr) - 1:
            s += '}'
        res += s
    return res


def do_submit(proxy_region: str, send_title_link: str, submitdata: str, sleep_time: int, wo_topic_id):
    # print('do_submit提交数据，wo_topic_id:', wo_topic_id)
    # 获取品赞代理
    virtual_proxy_area = proxy_region
    if proxy_region in OVERSEA_REGIONS:  # 海外发送请求，默认先使用国内的'全国'请求地址，最后发送的时候改为获取海外的ip
        virtual_proxy_area = 'all'
    pz_obj = PinzanHttpProxy(virtual_proxy_area)
    pz_obj.get_proxy()
    # 创建问卷对象, 发送请求
    qo = QuestionareSpider(send_title_link=send_title_link, pz_obj=pz_obj, wo_topic_id=wo_topic_id,
                           sleep_time=sleep_time, area=proxy_region)
    res = qo.submit(submitdata)  # 提交
    print(submitdata)
    return res, pz_obj.host_port_city


# 定义一个函数，用于执行sleep操作
def sleep_10_seconds(args1, args2):
    submitdata = '1$1}2$1}3$信息工程学院}4$1}5$1}6$4}7$4}8$3}9$2}10$2}11$1|2}12$1}13$2}14$2'
    sleep_time = random.randint(20, 40)
    res, ip_res = do_submit('', 'https://www.wjx.cn/m/18475388.aspx#', submitdata, sleep_time, '1_1')
    print(res)
    print(ip_res)
    print('任务', args1, '运行完成')


# Press the green button in the gutter to run the script.
if __name__ == '__main__':
    pass
# for i in range(10):
#     time.sleep(0.002)  # 睡2毫秒，防止生成相同的task_id
#     task_id = str('1') + '_child_' + str(int(time.time() * 1000))  # 根据时间戳(ms)作为唯一表示
#     a = datetime.datetime.now() + datetime.timedelta(milliseconds=100)
#     run_time = a.strftime("%Y-%m-%d %H:%M:%S.%f")  # 生成每组数据的间隔时间(秒)
#     scheduler.add_job(sleep_10_seconds, 'date', run_date=run_time, id=task_id, jobstore='default', args=(i, 2))
# # 启动调度器
#
# print("所有方法已在后台运行")
# time.sleep(1000)
# print('程序执行结束')
# print(execjs.get().name)

# 模拟使用指定IP发送请求
# headers = dict()
# headers['accept'] = ('text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;'
#                      'q=0.8,application/signed-exchange;v=b3;q=0.9')
# headers['user-agent'] = ('Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) '
#                          'Chrome/98.0.4758.102 Safari/537.36 NetType/WIFI MicroMessenger/6.8.0(0x16080000) '
#                          'MacWechat/3.8.3(0x13080310) XWEB/30817 Flue')
# ip = '101.37.42.250'
# headers['X-Real-ip'] = ip
# headers['x-forwarded-for'] = ip
# headers['x-remote-IP'] = ip
#
# url = ('https://api.weixin.qq.com/cgi-bin/token?'
#        'grant_type=client_credential&appid=wx8fe84c5d52db247a&secret=0ea8e1a7f5154c2e4edb15dde3493dee425a17a7')
# # 代理服务器的地址和端口
# proxy = 'http://IP_ADDRESS:PORT'
# # 设置代理服务器
# ip_and_port = ip + ':' + '8000'
# proxies = {'http': ip_and_port, 'https': ip_and_port}
# response = requests.get(url, headers=headers, proxies=proxies)
# print(response.text)

# print('开始时间：', datetime.datetime.now())
# for i in range(1000):
#     try:
#
#         config = env_config.config_mapping()
#         sig_token_url = config.get('WJX_7_CHECK_SERVER')
#         # callback_response = requests.get(sig_token_url + '/sign?url=' + 'https://www.wjx.cn/vm/Q0wTmRF.aspx')
#         # title_url = 'https://www.wjx.cn/vm/Q0wTmRF.aspx'
#         title_url = 'https://www.wjx.cn/vm/w70ZjFc.aspx'
#         # proxy_meta = 'http://T0B8F090JPO:u75guaahnuhk21o@218.95.39.50:12650'  # "expired":1700920336497
#         proxy_meta = 'http://T0B8F090JPO:u75guaahnuhk21o@218.95.39.19:12429'  # "expired":1700925044461
#         url = '%s/sign?url=%s&proxy_url=%s&work_order_id=%s' % (sig_token_url, title_url, proxy_meta, 123)
#         callback_response = requests.get(url)
#
#         data = callback_response.content.decode()
#         # sleep_time = random.uniform(4, 6)
#         # time.sleep(sleep_time)
#         # print('打印次数:', i, 'sleep', sleep_time, '秒：结果', data)
#         print('打印次数:', i, '秒：结果', data)
#     except Exception as e:
#         print(e)
#         continue
# if data:
#     data_json = json.loads(data)
#     sign = data_json.get('sign')
#     inner_data = data_json.get('data')
#     if sign and inner_data:  # 若都获取到，则继续往下解析，否则直接返回
#         # 提取有效的JSON部分，并解析为JSON对象
#         sign_data = inner_data[inner_data.index('(') + 1: inner_data.rindex(')')]
#         sign_res = json.loads(sign_data)
#         nc_csessionid = ''
#         nc_sig = ''
#         nc_token = ''
#         nc_scene = ''
#         if sign_res:
#             sig_success = sign_res.get('success')
#             if sig_success:
#                 sig_result = sign_res.get('result')
#                 if sig_result and sig_result.get('success') and sig_result.get('code') == 200:
#                     # 说明获取成功
#                     inner_result = sig_result.get('result')
#                     if inner_result:
#                         nc_csessionid = inner_result.get('sessionId')
#                         nc_sig = inner_result.get('sig')
#         sign_cookie = json.loads(sign)
#         if sign_cookie:
#             # a = sign_cookie.get('a')
#             nc_token = sign_cookie.get('c')
#             nc_scene = sign_cookie.get('d')
#         print('nc_csessionid:', nc_csessionid, ',nc_sig:', nc_sig, ',nc_token:', nc_token, ',nc_scene:', nc_scene)

# See PyCharm help at https://www.jetbrains.com/help/pycharm/

# 1$无^无^无^无}2$无}3$1!962!153!69}4$1!1;7;9;112!1;7;9;113!1;7;9;11}5$1!无^2!无

# 1$A^30^138^10}2$B}3$1!7^2!16^3!25}4$1!1;2;3,2!2;3,3!1;2;3;4}5$1!waiguan1^2!gongneng1
